knitr::opts_chunk$set(dpi = 300, fig.path = 'fig/', fig.width = 12, fig.height = 8)

library(tidymodels)
library(modeltime.h2o)
library(tidyverse)
library(timetk)
library(readxl)
library(readr)

cv <- read_excel("data/cv.xlsx") %>% mutate(Date = as.Date(Date))
cv2 <- cv

d1 <- read_delim("data/fb1", "\t", escape_double = FALSE, trim_ws = TRUE)

-- Column specification -------------------------------------------------------------------
cols(
  ds = col_date(format = ""),
  country = col_character(),
  polygon_source = col_character(),
  polygon_id = col_character(),
  polygon_name = col_character(),
  all_day_bing_tiles_visited_relative_change = col_double(),
  all_day_ratio_single_tile_users = col_double(),
  baseline_name = col_character(),
  baseline_type = col_character()
)
d2 <- read_delim("data/fb2", "\t", escape_double = FALSE, trim_ws = TRUE)

-- Column specification -------------------------------------------------------------------
cols(
  ds = col_date(format = ""),
  country = col_character(),
  polygon_source = col_character(),
  polygon_id = col_character(),
  polygon_name = col_character(),
  all_day_bing_tiles_visited_relative_change = col_double(),
  all_day_ratio_single_tile_users = col_double(),
  baseline_name = col_character(),
  baseline_type = col_character()
)
lk <- d1 %>% filter(country == 'LKA')
lk <- lk %>% rbind(d2 %>% filter(country == 'LKA')) %>% group_by(ds) %>% summarise(adb = mean(all_day_bing_tiles_visited_relative_change), ar = mean(all_day_ratio_single_tile_users)) %>% rename(Date = ds)

cv <- cv %>% left_join(lk) %>% tk_augment_lags(.,c('adb', 'ar'), .lags = seq(1,20,by = 4))
Joining, by = "Date"

Data splitting - The most recent 1 month as the assessment split

cv %>% plot_time_series(.date_var = Date, n)


splits <- time_series_split(cv, assess = "45 day", cumulative = TRUE)
Using date_var: Date
splits2 <- time_series_split(cv2, assess = "45 day", cumulative = TRUE)
Using date_var: Date
recipe_spec <- recipe(n ~ ., data = training(splits)) %>%
    step_timeseries_signature(Date)
recipe_spec2 <- recipe(n ~ ., data = training(splits2)) %>%
    step_timeseries_signature(Date)

train_tbl <- training(splits) %>% bake(prep(recipe_spec), .)
test_tbl  <- testing(splits) %>% bake(prep(recipe_spec), .)

train_tbl2 <- training(splits2) %>% bake(prep(recipe_spec), .)
test_tbl2  <- testing(splits2) %>% bake(prep(recipe_spec), .)

h2o.init(
    nthreads = -1,
    ip       = 'localhost',
    port     = 54321
)
 Connection successful!

R is connected to the H2O cluster: 
    H2O cluster uptime:         10 hours 50 minutes 
    H2O cluster timezone:       Asia/Colombo 
    H2O data parsing timezone:  UTC 
    H2O cluster version:        3.32.1.5 
    H2O cluster version age:    10 days  
    H2O cluster name:           H2O_started_from_R_Supun_aww077 
    H2O cluster total nodes:    1 
    H2O cluster total memory:   0.77 GB 
    H2O cluster total cores:    4 
    H2O cluster allowed cores:  4 
    H2O cluster healthy:        TRUE 
    H2O Connection ip:          localhost 
    H2O Connection port:        54321 
    H2O Connection proxy:       NA 
    H2O Internal Security:      FALSE 
    H2O API Extensions:         Amazon S3, Algos, AutoML, Core V3, TargetEncoder, Core V4 
    R Version:                  R version 3.6.3 (2020-02-29) 
model_spec <- automl_reg(mode = 'regression') %>%
    set_engine(
         engine                     = 'h2o',
         max_runtime_secs           = 30, 
         max_runtime_secs_per_model = 10,
         max_models                 = 3,
         nfolds                     = 5,
         exclude_algos              = c(),
         verbosity                  = 1,
         seed                       = 786
    ) 
model_spec
H2O AutoML Model Specification (regression)

Engine-Specific Arguments:
  max_runtime_secs = 30
  max_runtime_secs_per_model = 10
  max_models = 3
  nfolds = 5
  exclude_algos = c()
  verbosity = 1
  seed = 786

Computational engine: h2o 
model_fitted <- model_spec %>%
    fit(n ~ ., data = train_tbl)
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

Training H2O AutoML...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |====                                                                             |   5%
  |                                                                                       
  |=======                                                                          |   8%
  |                                                                                       
  |==========                                                                       |  12%
  |                                                                                       
  |============                                                                     |  15%
  |                                                                                       
  |===============                                                                  |  19%
  |                                                                                       
  |==================                                                               |  22%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                                
  |                                                                                          |   0%
  |                                                                                                
  |==========================================================================================| 100%


Leaderboard: 

[5 rows x 6 columns] 

Using top model: StackedEnsemble_BestOfFamily_AutoML_20210815_183318
View(cv)
model_fitted2 <- model_spec %>%
    fit(n ~ ., data = train_tbl2)
Converting to H2OFrame...

  |                                                                                                
  |                                                                                          |   0%
  |                                                                                                
  |==========================================================================================| 100%

Training H2O AutoML...

  |                                                                                                
  |                                                                                          |   0%
  |                                                                                                
  |====                                                                                      |   5%
  |                                                                                                
  |========                                                                                  |   8%
  |                                                                                                
  |===========                                                                               |  12%
  |                                                                                                
  |==============                                                                            |  15%
  |                                                                                                
  |=================                                                                         |  19%
  |                                                                                                
  |====================                                                                      |  22%
  |                                                                                                
  |==========================================================================================| 100%

  |                                                                                                
  |                                                                                          |   0%
  |                                                                                                
  |==========================================================================================| 100%


Leaderboard: 

[5 rows x 6 columns] 

Using top model: StackedEnsemble_BestOfFamily_AutoML_20210815_183342

Final Model

model_fitted2
parsnip model object

Fit time:  24.6s 

H2O AutoML - Stackedensemble
--------
Model: Model Details:
==============

H2ORegressionModel: stackedensemble
Model ID:  StackedEnsemble_BestOfFamily_AutoML_20210815_183342 
Number of Base Models: 3

Base Models (count by algorithm type):

drf gbm glm 
  1   1   1 

Metalearner:

Metalearner algorithm: glm
Metalearner cross-validation fold assignment:
  Fold assignment scheme: AUTO
  Number of folds: 5
  Fold column: NULL
Metalearner hyperparameters: 


H2ORegressionMetrics: stackedensemble
** Reported on training data. **

MSE:  633.7107
RMSE:  25.17361
MAE:  15.46799
RMSLE:  0.4973546
Mean Residual Deviance :  633.7107



H2ORegressionMetrics: stackedensemble
** Reported on cross-validation data. **
** 5-fold cross-validation on training data (Metrics computed for combined holdout predictions) **

MSE:  9218.817
RMSE:  96.01467
MAE:  49.08651
RMSLE:  0.7351128
Mean Residual Deviance :  9218.817
model_fitted
parsnip model object

Fit time:  21.7s 

H2O AutoML - Stackedensemble
--------
Model: Model Details:
==============

H2ORegressionModel: stackedensemble
Model ID:  StackedEnsemble_BestOfFamily_AutoML_20210815_183318 
Number of Base Models: 3

Base Models (count by algorithm type):

drf gbm glm 
  1   1   1 

Metalearner:

Metalearner algorithm: glm
Metalearner cross-validation fold assignment:
  Fold assignment scheme: AUTO
  Number of folds: 5
  Fold column: NULL
Metalearner hyperparameters: 


H2ORegressionMetrics: stackedensemble
** Reported on training data. **

MSE:  967.0529
RMSE:  31.09747
MAE:  19.61695
RMSLE:  0.4347607
Mean Residual Deviance :  967.0529



H2ORegressionMetrics: stackedensemble
** Reported on cross-validation data. **
** 5-fold cross-validation on training data (Metrics computed for combined holdout predictions) **

MSE:  10962.94
RMSE:  104.7041
MAE:  58.95527
RMSLE:  NaN
Mean Residual Deviance :  10962.94

No Mobility data

modeltime_tbl <- modeltime_table(
    model_fitted2
) 

modeltime_tbl %>%
  modeltime_calibrate(test_tbl2) %>%
    modeltime_forecast(
        new_data    = test_tbl2,
        actual_data = cv2,
        keep_data   = TRUE
    ) %>%
    plot_modeltime_forecast(
        .interactive = TRUE
    )
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

data_prepared_tbl <- bind_rows(train_tbl2, test_tbl2)

future_tbl <- data_prepared_tbl %>%
    future_frame(.length_out = "9 month")
.date_var is missing. Using: Date
future_prepared_tbl <- bake(prep(recipe_spec), future_tbl)

refit_tbl <- modeltime_tbl %>%
    modeltime_refit(data_prepared_tbl)
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

Training H2O AutoML...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |====                                                                             |   5%
  |                                                                                       
  |=======                                                                          |   9%
  |                                                                                       
  |==========                                                                       |  12%
  |                                                                                       
  |=============                                                                    |  16%
  |                                                                                       
  |================                                                                 |  19%
  |                                                                                       
  |===================                                                              |  23%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%


Leaderboard: 

[5 rows x 6 columns] 

Using top model: StackedEnsemble_BestOfFamily_AutoML_20210815_183414
refit_tbl %>%
    modeltime_forecast(
        new_data    = future_prepared_tbl,
        actual_data = data_prepared_tbl,
        keep_data   = TRUE
    ) %>%
    plot_modeltime_forecast(
        .interactive = TRUE,.conf_interval_show = TRUE
    )
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%
Expecting the following names to be in the data frame: .conf_hi, .conf_lo. 
Proceeding with '.conf_interval_show = FALSE' to visualize the forecast without confidence intervals.
Alternatively, try using `modeltime_calibrate()` before forecasting to add confidence intervals.

With Mobility data

modeltime_tbl <- modeltime_table(
    model_fitted
) 

modeltime_tbl %>%
  modeltime_calibrate(test_tbl) %>%
    modeltime_forecast(
        new_data    = test_tbl,
        actual_data = cv,
        keep_data   = TRUE
    ) %>%
    plot_modeltime_forecast(
        .interactive = TRUE
    )
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

data_prepared_tbl <- bind_rows(train_tbl, test_tbl)

refit_tbl <- modeltime_tbl %>%
    modeltime_refit(data_prepared_tbl)
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

Training H2O AutoML...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=                                                                                |   1%
  |                                                                                       
  |====                                                                             |   5%
  |                                                                                       
  |=======                                                                          |   8%
  |                                                                                       
  |==========                                                                       |  12%
  |                                                                                       
  |=============                                                                    |  16%
  |                                                                                       
  |===============                                                                  |  19%
  |                                                                                       
  |==================                                                               |  22%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%


Leaderboard: 

[5 rows x 6 columns] 

Using top model: StackedEnsemble_BestOfFamily_AutoML_20210815_183444

With avg mobility

future_tbl <- data_prepared_tbl %>%
    future_frame(.length_out = "9 month")
.date_var is missing. Using: Date
future_prepared_tbl <- bake(prep(recipe_spec), future_tbl) %>% mutate(adb = -0.4, ar = 0.3) %>% tk_augment_lags(.,c('adb', 'ar'), .lags = seq(1,20,by = 4))


refit_tbl %>%
    modeltime_forecast(
        new_data    = future_prepared_tbl,
        actual_data = data_prepared_tbl,
        keep_data   = TRUE
    ) %>%
    plot_modeltime_forecast(
        .interactive = TRUE,.conf_interval_show = TRUE
    )
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%
Expecting the following names to be in the data frame: .conf_hi, .conf_lo. 
Proceeding with '.conf_interval_show = FALSE' to visualize the forecast without confidence intervals.
Alternatively, try using `modeltime_calibrate()` before forecasting to add confidence intervals.

With max mobility

future_prepared_tbl <- bake(prep(recipe_spec), future_tbl) %>% mutate(adb = 0, ar = 0) %>% tk_augment_lags(.,c('adb', 'ar'), .lags = seq(1,20,by = 4))

refit_tbl %>%
    modeltime_forecast(
        new_data    = future_prepared_tbl,
        actual_data = data_prepared_tbl,
        keep_data   = TRUE
    ) %>%
    plot_modeltime_forecast(
        .interactive = TRUE,.conf_interval_show = TRUE
    )
Converting to H2OFrame...

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%

  |                                                                                       
  |                                                                                 |   0%
  |                                                                                       
  |=================================================================================| 100%
Expecting the following names to be in the data frame: .conf_hi, .conf_lo. 
Proceeding with '.conf_interval_show = FALSE' to visualize the forecast without confidence intervals.
Alternatively, try using `modeltime_calibrate()` before forecasting to add confidence intervals.
LS0tDQp0aXRsZTogIkNPVklEIDE5IFRpbWUgU2VyaWVzIEFuYWx5c2lzIC0gNDUgZGF5LiBXaXRoIGRpZmZlcmVudCBtb2JpbGl0aWVzIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQpgYGB7cn0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChkcGkgPSAzMDAsIGZpZy5wYXRoID0gJ2ZpZy8nLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDgpDQoNCmxpYnJhcnkodGlkeW1vZGVscykNCmxpYnJhcnkobW9kZWx0aW1lLmgybykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeSh0aW1ldGspDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkocmVhZHIpDQoNCmN2IDwtIHJlYWRfZXhjZWwoImRhdGEvY3YueGxzeCIpICU+JSBtdXRhdGUoRGF0ZSA9IGFzLkRhdGUoRGF0ZSkpDQpjdjIgPC0gY3YNCg0KZDEgPC0gcmVhZF9kZWxpbSgiZGF0YS9mYjEiLCAiXHQiLCBlc2NhcGVfZG91YmxlID0gRkFMU0UsIHRyaW1fd3MgPSBUUlVFKQ0KZDIgPC0gcmVhZF9kZWxpbSgiZGF0YS9mYjIiLCAiXHQiLCBlc2NhcGVfZG91YmxlID0gRkFMU0UsIHRyaW1fd3MgPSBUUlVFKQ0KDQpsayA8LSBkMSAlPiUgZmlsdGVyKGNvdW50cnkgPT0gJ0xLQScpDQpsayA8LSBsayAlPiUgcmJpbmQoZDIgJT4lIGZpbHRlcihjb3VudHJ5ID09ICdMS0EnKSkgJT4lIGdyb3VwX2J5KGRzKSAlPiUgc3VtbWFyaXNlKGFkYiA9IG1lYW4oYWxsX2RheV9iaW5nX3RpbGVzX3Zpc2l0ZWRfcmVsYXRpdmVfY2hhbmdlKSwgYXIgPSBtZWFuKGFsbF9kYXlfcmF0aW9fc2luZ2xlX3RpbGVfdXNlcnMpKSAlPiUgcmVuYW1lKERhdGUgPSBkcykNCg0KY3YgPC0gY3YgJT4lIGxlZnRfam9pbihsaykNCmBgYA0KDQpEYXRhIHNwbGl0dGluZyAtIFRoZSBtb3N0IHJlY2VudCAxIG1vbnRoIGFzIHRoZSBhc3Nlc3NtZW50IHNwbGl0DQpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0NCmN2ICU+JSBwbG90X3RpbWVfc2VyaWVzKC5kYXRlX3ZhciA9IERhdGUsIG4pDQoNCnNwbGl0cyA8LSB0aW1lX3Nlcmllc19zcGxpdChjdiwgYXNzZXNzID0gIjQ1IGRheSIsIGN1bXVsYXRpdmUgPSBUUlVFKQ0Kc3BsaXRzMiA8LSB0aW1lX3Nlcmllc19zcGxpdChjdjIsIGFzc2VzcyA9ICI0NSBkYXkiLCBjdW11bGF0aXZlID0gVFJVRSkNCg0KcmVjaXBlX3NwZWMgPC0gcmVjaXBlKG4gfiAuLCBkYXRhID0gdHJhaW5pbmcoc3BsaXRzKSkgJT4lDQogICAgc3RlcF90aW1lc2VyaWVzX3NpZ25hdHVyZShEYXRlKQ0KcmVjaXBlX3NwZWMyIDwtIHJlY2lwZShuIH4gLiwgZGF0YSA9IHRyYWluaW5nKHNwbGl0czIpKSAlPiUNCiAgICBzdGVwX3RpbWVzZXJpZXNfc2lnbmF0dXJlKERhdGUpDQoNCnRyYWluX3RibCA8LSB0cmFpbmluZyhzcGxpdHMpICU+JSBiYWtlKHByZXAocmVjaXBlX3NwZWMpLCAuKQ0KdGVzdF90YmwgIDwtIHRlc3Rpbmcoc3BsaXRzKSAlPiUgYmFrZShwcmVwKHJlY2lwZV9zcGVjKSwgLikNCg0KdHJhaW5fdGJsMiA8LSB0cmFpbmluZyhzcGxpdHMyKSAlPiUgYmFrZShwcmVwKHJlY2lwZV9zcGVjKSwgLikNCnRlc3RfdGJsMiAgPC0gdGVzdGluZyhzcGxpdHMyKSAlPiUgYmFrZShwcmVwKHJlY2lwZV9zcGVjKSwgLikNCg0KaDJvLmluaXQoDQogICAgbnRocmVhZHMgPSAtMSwNCiAgICBpcCAgICAgICA9ICdsb2NhbGhvc3QnLA0KICAgIHBvcnQgICAgID0gNTQzMjENCikNCm1vZGVsX3NwZWMgPC0gYXV0b21sX3JlZyhtb2RlID0gJ3JlZ3Jlc3Npb24nKSAlPiUNCiAgICBzZXRfZW5naW5lKA0KICAgICAgICAgZW5naW5lICAgICAgICAgICAgICAgICAgICAgPSAnaDJvJywNCiAgICAgICAgIG1heF9ydW50aW1lX3NlY3MgICAgICAgICAgID0gMzAsIA0KICAgICAgICAgbWF4X3J1bnRpbWVfc2Vjc19wZXJfbW9kZWwgPSAxMCwNCiAgICAgICAgIG1heF9tb2RlbHMgICAgICAgICAgICAgICAgID0gMywNCiAgICAgICAgIG5mb2xkcyAgICAgICAgICAgICAgICAgICAgID0gNSwNCiAgICAgICAgIGV4Y2x1ZGVfYWxnb3MgICAgICAgICAgICAgID0gYygpLA0KICAgICAgICAgdmVyYm9zaXR5ICAgICAgICAgICAgICAgICAgPSAxLA0KICAgICAgICAgc2VlZCAgICAgICAgICAgICAgICAgICAgICAgPSA3ODYNCiAgICApIA0KbW9kZWxfc3BlYw0KDQptb2RlbF9maXR0ZWQgPC0gbW9kZWxfc3BlYyAlPiUNCiAgICBmaXQobiB+IC4sIGRhdGEgPSB0cmFpbl90YmwpDQptb2RlbF9maXR0ZWQyIDwtIG1vZGVsX3NwZWMgJT4lDQogICAgZml0KG4gfiAuLCBkYXRhID0gdHJhaW5fdGJsMikNCmBgYA0KDQojIyMjIEZpbmFsIE1vZGVsDQpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0NCm1vZGVsX2ZpdHRlZDINCm1vZGVsX2ZpdHRlZA0KDQpgYGANCg0KDQojIyMjIE5vIE1vYmlsaXR5IGRhdGENCmBgYHtyICBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0NCm1vZGVsdGltZV90YmwgPC0gbW9kZWx0aW1lX3RhYmxlKA0KICAgIG1vZGVsX2ZpdHRlZDINCikgDQoNCm1vZGVsdGltZV90YmwgJT4lDQogIG1vZGVsdGltZV9jYWxpYnJhdGUodGVzdF90YmwyKSAlPiUNCiAgICBtb2RlbHRpbWVfZm9yZWNhc3QoDQogICAgICAgIG5ld19kYXRhICAgID0gdGVzdF90YmwyLA0KICAgICAgICBhY3R1YWxfZGF0YSA9IGN2MiwNCiAgICAgICAga2VlcF9kYXRhICAgPSBUUlVFDQogICAgKSAlPiUNCiAgICBwbG90X21vZGVsdGltZV9mb3JlY2FzdCgNCiAgICAgICAgLmludGVyYWN0aXZlID0gVFJVRQ0KICAgICkNCg0KZGF0YV9wcmVwYXJlZF90YmwgPC0gYmluZF9yb3dzKHRyYWluX3RibDIsIHRlc3RfdGJsMikNCg0KZnV0dXJlX3RibCA8LSBkYXRhX3ByZXBhcmVkX3RibCAlPiUNCiAgICBmdXR1cmVfZnJhbWUoLmxlbmd0aF9vdXQgPSAiOSBtb250aCIpDQoNCmZ1dHVyZV9wcmVwYXJlZF90YmwgPC0gYmFrZShwcmVwKHJlY2lwZV9zcGVjKSwgZnV0dXJlX3RibCkNCg0KcmVmaXRfdGJsIDwtIG1vZGVsdGltZV90YmwgJT4lDQogICAgbW9kZWx0aW1lX3JlZml0KGRhdGFfcHJlcGFyZWRfdGJsKQ0KDQpyZWZpdF90YmwgJT4lDQogICAgbW9kZWx0aW1lX2ZvcmVjYXN0KA0KICAgICAgICBuZXdfZGF0YSAgICA9IGZ1dHVyZV9wcmVwYXJlZF90YmwsDQogICAgICAgIGFjdHVhbF9kYXRhID0gZGF0YV9wcmVwYXJlZF90YmwsDQogICAgICAgIGtlZXBfZGF0YSAgID0gVFJVRQ0KICAgICkgJT4lDQogICAgcGxvdF9tb2RlbHRpbWVfZm9yZWNhc3QoDQogICAgICAgIC5pbnRlcmFjdGl2ZSA9IFRSVUUsLmNvbmZfaW50ZXJ2YWxfc2hvdyA9IFRSVUUNCiAgICApDQpgYGANCg0KIyMjIyBXaXRoIE1vYmlsaXR5IGRhdGENCg0KYGBge3IgIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQ0KbW9kZWx0aW1lX3RibCA8LSBtb2RlbHRpbWVfdGFibGUoDQogICAgbW9kZWxfZml0dGVkDQopIA0KDQptb2RlbHRpbWVfdGJsICU+JQ0KICBtb2RlbHRpbWVfY2FsaWJyYXRlKHRlc3RfdGJsKSAlPiUNCiAgICBtb2RlbHRpbWVfZm9yZWNhc3QoDQogICAgICAgIG5ld19kYXRhICAgID0gdGVzdF90YmwsDQogICAgICAgIGFjdHVhbF9kYXRhID0gY3YsDQogICAgICAgIGtlZXBfZGF0YSAgID0gVFJVRQ0KICAgICkgJT4lDQogICAgcGxvdF9tb2RlbHRpbWVfZm9yZWNhc3QoDQogICAgICAgIC5pbnRlcmFjdGl2ZSA9IFRSVUUNCiAgICApDQoNCmRhdGFfcHJlcGFyZWRfdGJsIDwtIGJpbmRfcm93cyh0cmFpbl90YmwsIHRlc3RfdGJsKQ0KDQpyZWZpdF90YmwgPC0gbW9kZWx0aW1lX3RibCAlPiUNCiAgICBtb2RlbHRpbWVfcmVmaXQoZGF0YV9wcmVwYXJlZF90YmwpDQoNCmBgYA0KDQojIyMjIFdpdGggYXZnIG1vYmlsaXR5DQoNCmBgYHtyICBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0NCmZ1dHVyZV90YmwgPC0gZGF0YV9wcmVwYXJlZF90YmwgJT4lDQogICAgZnV0dXJlX2ZyYW1lKC5sZW5ndGhfb3V0ID0gIjkgbW9udGgiKQ0KDQpmdXR1cmVfcHJlcGFyZWRfdGJsIDwtIGJha2UocHJlcChyZWNpcGVfc3BlYyksIGZ1dHVyZV90YmwpICU+JSBtdXRhdGUoYWRiID0gLTAuNCwgYXIgPSAwLjMpDQoNCg0KcmVmaXRfdGJsICU+JQ0KICAgIG1vZGVsdGltZV9mb3JlY2FzdCgNCiAgICAgICAgbmV3X2RhdGEgICAgPSBmdXR1cmVfcHJlcGFyZWRfdGJsLA0KICAgICAgICBhY3R1YWxfZGF0YSA9IGRhdGFfcHJlcGFyZWRfdGJsLA0KICAgICAgICBrZWVwX2RhdGEgICA9IFRSVUUNCiAgICApICU+JQ0KICAgIHBsb3RfbW9kZWx0aW1lX2ZvcmVjYXN0KA0KICAgICAgICAuaW50ZXJhY3RpdmUgPSBUUlVFLC5jb25mX2ludGVydmFsX3Nob3cgPSBUUlVFDQogICAgKQ0KYGBgDQoNCiMjIyMgV2l0aCBtYXggbW9iaWxpdHkNCg0KYGBge3IgIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQ0KZnV0dXJlX3ByZXBhcmVkX3RibCA8LSBiYWtlKHByZXAocmVjaXBlX3NwZWMpLCBmdXR1cmVfdGJsKSAlPiUgbXV0YXRlKGFkYiA9IDAsIGFyID0gMCkNCg0KcmVmaXRfdGJsICU+JQ0KICAgIG1vZGVsdGltZV9mb3JlY2FzdCgNCiAgICAgICAgbmV3X2RhdGEgICAgPSBmdXR1cmVfcHJlcGFyZWRfdGJsLA0KICAgICAgICBhY3R1YWxfZGF0YSA9IGRhdGFfcHJlcGFyZWRfdGJsLA0KICAgICAgICBrZWVwX2RhdGEgICA9IFRSVUUNCiAgICApICU+JQ0KICAgIHBsb3RfbW9kZWx0aW1lX2ZvcmVjYXN0KA0KICAgICAgICAuaW50ZXJhY3RpdmUgPSBUUlVFLC5jb25mX2ludGVydmFsX3Nob3cgPSBUUlVFDQogICAgKQ0KDQpgYGANCg0K